
import { reactive } from './reactive.js';
import Computed from './Computed.js';
import Watcher from './Watcher.js';

export class Vue {
  constructor(options) {
    // 解构获取传入的数据
    const { data, computed, watch } = options;

    this.$data = data();

    this.init(this, computed, watch);
  }

  init(vm, computed, watch) {
    this.initData(vm);
    const computedIns = this.initComputed(vm, computed);
    const watchIns = this.initWatcher(vm, watch);

    // 需要改变指向 this.$computed里的this -> Computed里的this
    this.$computed = computedIns.update.bind(computedIns);
    this.$watch = watchIns.invoke.bind(watchIns);
  }

  initData(vm) { // 数据初始化 -> 响应式
    reactive(vm, (key, value) => {
      console.log(key, value);
    }, (key, newVal, oldVal) => {
      // set 的时候进行computed 计算(更新)
      // console.log(key, 'newVal: ' + newVal, 'oldVal: ' + oldVal);
      if (newVal === oldVal) return;

      this.$computed(key, this.$watch); // 计算(调用computed)的同时也需要侦听
      this.$watch(key, newVal, oldVal);
    })
  }

  initComputed(vm, computed) {
    // 枚举computed -> 增加computedData
    // 返回实例 -> 实例里有update -> 更新 computedData 里的value
    // console.log(computed);
    const computedIns = new Computed();
    for(let key in computed) {
      computedIns.addComputed(vm, computed, key);
    }

    return computedIns;
  }

  initWatcher(vm, watch) {
    // 枚举watcher -> 增加侦听器
    // 返回实例 -> 实例里有调用watch的方法 -> 执行侦听器
    const watchIns = new Watcher();
    for (let key in watch) {
      watchIns.addWatcher(vm, watch, key)
    }

    return watchIns;
  }
  
}
